from django.db import models
from django.db.models import F
from django.contrib.auth.models import AbstractUser, BaseUserManager
from core.wchat.wx_base import mc
from core.tl.client import get_TLClient
from core.tools.models import PublicPrivate
from apps.coffee.config import system_user


# 级别描述
class LevelDesc(models.Model):
    # Level = 1、普通用户 2、正式会员 3、黄金会员 4、钻石会员
    Level = ((1, "普通用户"), (2, "正式会员"), (3, "服务商"), (4, "金牌服务商"))
    level = models.IntegerField(default=1, verbose_name="等级", unique=True, choices=Level)
    num = models.IntegerField(verbose_name="推荐人数", default=0)
    cash_num = models.IntegerField(verbose_name="消费金额", default=0)

    leader = models.ForeignKey("self", verbose_name="上级", blank=True, null=True)

    class Meta:
        verbose_name = "级别描述表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.get_level_display()


class UserProfileManager(BaseUserManager):
    def get_or_create_user(self, mobile, coffee_channel=None):
        user, created = self.get_or_create(
            mobile=mobile,
            username=mobile,
        )
        if created:
            user.coffee_new_user = True
            user.coffee_channel = coffee_channel
        if user.level:
            return user, created
        else:
            user.level = LevelDesc.objects.get(level=1)
            user.save()
        return user, created


# 用户表
class UserProfile(AbstractUser):
    """
    用户
    """
    UserType = ((1, "商户"), (2, "门店"))
    # user_type = models.IntegerField(blank=True, null=True, choices=UserType, verbose_name="用户类型")
    qr_code = models.CharField(blank=True, null=True, verbose_name="推广二维码", max_length=128)
    wx_user = models.OneToOneField("wchat.WxUserInfo", verbose_name="微信用户", blank=True, null=True)
    wx_mini_user = models.OneToOneField("wchat.MiniWxUserInfo", verbose_name="微信小程序用户", blank=True, null=True)
    ali_user = models.OneToOneField("alipay.AliUser", verbose_name="支付宝用户", blank=True, null=True)
    zx_user = models.OneToOneField("zhongxin.ZXUser", verbose_name="中信用户", blank=True, null=True)
    flag = models.BooleanField(verbose_name="优秀服务商标记", db_index=True, default=False)
    user_code = models.CharField(blank=True, null=True, max_length=10, db_index=True, verbose_name="推荐码")
    name = models.CharField(max_length=16, blank=True, null=True, verbose_name="会员名")
    birthday = models.DateField(blank=True, null=True, verbose_name="出生年月")
    mobile = models.CharField(max_length=16, blank=True, null=True, verbose_name="手机号")
    email = models.CharField(max_length=32, blank=True, null=True, verbose_name="邮箱")
    level = models.ForeignKey("LevelDesc", verbose_name="级别", blank=True, null=True)
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    leader = models.ForeignKey("self", verbose_name="上级人员", blank=True, null=True, related_name="leader_set")
    lower_num = models.IntegerField(verbose_name="下级会员数", default=0)
    can_transfer = models.BooleanField(verbose_name="是否可以提现", default=True)
    real_name = models.CharField(max_length=16, verbose_name="真实姓名", blank=True, null=True)
    bank = models.ForeignKey("tools.BankCode", verbose_name="银行", blank=True, null=True)
    bank_card_no = models.CharField(max_length=20, verbose_name="银卡号", blank=True, null=True)
    company = models.ForeignKey("supply_order.Company", blank=True, null=True, verbose_name="用户公司", db_index=True)
    header_img = models.ImageField(upload_to="shop/header_img", blank=True, null=True)
    user_perf = models.IntegerField(verbose_name="绩效", default=0)
    lower_is_vip = models.BooleanField(default=False, verbose_name="下级是会员")
    lower_vip_end_time = models.DateTimeField(blank=True, null=True, verbose_name="下级注册进来就是会员的结束时间")
    public_account = models.ForeignKey("PublicAccount", blank=True, null=True, verbose_name="对应的微信公众号")
    show_qr_code = models.BooleanField(verbose_name="展示二维码", default=True)
    show_public_account = models.BooleanField(verbose_name="展示关注公众号", default=True)
    oil_flag = models.BooleanField(verbose_name="加油权限", default=False)
    oil_flag_expiry_date = models.DateField(verbose_name="加油权益有效期", blank=True, null=True)
    czb_channel_auth = models.ManyToManyField("czb.ChannelRiseInPrice", blank=True, null=True,
                                              verbose_name="对应车主邦渠道登录")
    is_coffee_admin = models.BooleanField(default=False, db_index=True, verbose_name="咖啡管理员")
    coffee_channel = models.ForeignKey("coffee.Channel", verbose_name="coffee渠道", blank=True, null=True)
    is_coffee_manager = models.BooleanField(default=False, db_index=True, verbose_name="咖啡客户经理")
    coffee_new_user = models.BooleanField(default=True, verbose_name="coffee新用户")
    can_share_coupon = models.BooleanField(default=False, verbose_name="可以分享随机券")

    objects = UserProfileManager()

    class Meta:
        verbose_name = "用户"
        verbose_name_plural = verbose_name

    # 升级（根据推荐人个数判断）
    def level_up(self):
        if self.level.level == 1:
            pass
        # 如果还有比我当前级别高的级别, 并且我推荐个数比我高基本要求的数量多，升级
        if self.level.leader and self.lower_num >= self.level.leader.num:
            self.level = self.level.leader
            self.save()

    # 推荐人(当前instance是推荐人)
    def update_lower_num(self):
        self.lower_num = F("lower_num") + 1
        self.save()
        self.refresh_from_db()
        user_leader = self.leader
        # 如果他上级还有上级, 并且上级的上级是服务商
        if user_leader and user_leader.level.level >= 3:
            user_leader.lower_num = F("lower_num") + 1
            user_leader.save()
            user_leader.refresh_from_db()

    # 更新绩效（购买人）
    def update_user_perf(self, user_perf, operation="+"):
        """
        self 购买人
        :param user_perf: 绩效
        :param operation: 操作
        :return: 完成更新的用户列表
        """
        # 更新绩效涉及的用户
        relation_users = [self]
        # 谁买的谁加上
        if operation == "+":
            self.user_perf = F("user_perf") + user_perf
        else:
            self.user_perf = F("user_perf") - user_perf
        self.save()
        self.refresh_from_db()
        user_leader = self.leader
        # 有上级也加上
        if user_leader:
            if operation == "+":
                user_leader.user_perf = F("user_perf") + user_perf
            else:
                user_leader.user_perf = F("user_perf") - user_perf
            relation_users.append(user_leader)
            user_leader.save()
            user_leader.refresh_from_db()
            # 上级的上级是服务商以上级别 加上
            leader_leader = user_leader.leader
            if leader_leader and user_leader.level.level >= 3:
                relation_users.append(leader_leader)
                if operation == "+":
                    leader_leader.user_perf = F("user_perf") + user_perf
                else:
                    leader_leader.user_perf = F("user_perf") - user_perf
                leader_leader.save()
                leader_leader.refresh_from_db()
        # 从最大往下找
        print(relation_users)
        relation_users.reverse()
        return relation_users

    # 判断脱队
    def drop_out(self):
        # 如果有上级
        if self.leader:
            # 自己的级别比上级还大
            if self.level.level > self.leader.level.level:
                # 脱队到小优上
                self.leader = UserProfile.objects.get(mobile=system_user)
                self.save()

    # 成为会员
    def recommend(self):
        # 如果上级是普通用户
        if self.leader.level.level == 1:
            self.level = LevelDesc.objects.get(level=2)
            self.leader = UserProfile.objects.get(mobile=system_user)
            self.save()
        else:
            self.level = LevelDesc.objects.get(level=2)
            self.save()
            # 更新lower_num
            # 新逻辑 会员个数增加不升级
            # self.leader.update_lower_num()
            # # 上级升级
            # self.leader.level_up()
            # # 上上级升级
            # if self.leader.leader:
            #     self.leader.leader.level_up()
            # # 先判断升级，后判断掉队
            # # 上级掉队
            # self.leader.drop_out()
            # # 上上级掉队
            # if self.leader.leader:
            #     self.leader.leader.drop_out()

    # 根据销售额升级
    def level_up_by_sales(self):
        print(self.level.leader)
        print(self.user_perf)
        if self.level.leader and self.user_perf >= self.level.leader.cash_num:
            self.level = self.level.leader
            print(self.level.leader.cash_num)
            self.save()
            return True
        else:
            return False

    def __str__(self):
        return self.username

        # @staticmethod
        # @receiver(post_save, sender="user_operation.UserProfile")
        # def update_code(sender, **kwargs):
        #     instance = kwargs.get("instance")
        #     if instance.user_code:
        #         pass
        #     else:
        #         code = str(instance.pk)
        #         num = 10 - len(code)
        #         instance.user_code = "0" * num + code
        #         instance.save()


# 其他第三方平台
class UserProfileExtend(models.Model):
    """
    通联用户
    """
    user = models.OneToOneField(UserProfile, verbose_name="用户")
    userId = models.CharField(verbose_name="通联用户编号", max_length=32, db_index=True, blank=True, null=True)

    class Meta:
        verbose_name = "用户"
        verbose_name_plural = verbose_name

    def get_tl_user_id(self):
        """
        获取通联用户编号user_id 如果没有就去注册
        :return:
        """
        if self.userId:
            return self.userId
        else:
            h5_client = get_TLClient()
            token_key = h5_client.token_key(self.user_id)
            # response = h5_client.register_get_token(self.user.mobile, self.user.mobile)
            response = h5_client.register_get_token(self.user.mobile, self.user_id)
            token = response.get("token")
            userId = response.get("userId")
            self.userId = userId
            self.save()
            mc.set(token_key, token, 60 * 4)
            return userId

    def get_tl_user_token(self, h5_client):
        token_key = h5_client.token_key(self.user_id)
        if self.userId:
            token = mc.get(token_key)
            if token:
                return token
            response = h5_client.login_get_token(self.userId)
            token = response.get("token")
            mc.set(token_key, token, 60 * 4)
            return token
        else:
            # response = h5_client.register_get_token(self.user.mobile, self.user.mobile)
            response = h5_client.register_get_token(self.user.mobile, self.user_id)
            token = response.get("token")
            userId = response.get("userId")
            if token:
                self.userId = userId
                self.save()
                self.refresh_from_db()
                mc.set(token_key, token, 60 * 4)
                return token
            else:
                response = h5_client.login_get_token(userId)
                token = response.get("token")
                mc.set(token_key, token, 60 * 4)
                return token


# 购买用户上级分配关系
class BuyUserLeaderIncomeAllot(models.Model):
    buy_user_level = models.ForeignKey("LevelDesc", verbose_name="购买用户等级", related_name="buy_user_level_desc")
    income_user_level = models.ForeignKey("LevelDesc", verbose_name="收入用户等级",
                                          related_name="income_user_level_desc")
    allot = models.DecimalField(max_digits=3, decimal_places=2, default=0, verbose_name="比例", help_text="小数")

    class Meta:
        verbose_name = "购买用户上级分配关系"
        verbose_name_plural = verbose_name


# 上下级分配关系
class LeaderLowerIncomeAllot(models.Model):
    leader_user_level = models.ForeignKey("LevelDesc", verbose_name="上级等级", related_name="leader_user_level_desc")
    lower_user_level = models.ForeignKey("LevelDesc", verbose_name="下级等级", related_name="lower_user_level_desc")
    allot = models.DecimalField(max_digits=3, decimal_places=2, default=0, verbose_name="比例", help_text="小数")

    class Meta:
        verbose_name = "上下级分配关系"
        verbose_name_plural = verbose_name


# 会员礼包佣金分配
class VipBagCashAllot(models.Model):
    level = models.ForeignKey("LevelDesc", related_name="cash_allot_level", verbose_name="推荐人级别")
    income = models.IntegerField(verbose_name="收入", default=0, help_text="以分为单位")

    class Meta:
        verbose_name = "会员礼包分配表"
        verbose_name_plural = verbose_name


# 菜单
class Menus(models.Model):
    name = models.CharField(verbose_name="名称", max_length=64)
    url = models.CharField(verbose_name="路由", max_length=64)
    parents = models.ForeignKey("self", verbose_name="父菜单", blank=True, null=True, related_name="child_menus")
    company = models.ManyToManyField("supply_order.Company", verbose_name="对应的公司")

    class Meta:
        verbose_name = "商家后台菜单"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


# 渠道微信公众号信息
class PublicAccount(models.Model):
    company = models.CharField(verbose_name="公司", max_length=32)
    sign = models.CharField(verbose_name="标识", max_length=32)
    qr_code = models.CharField(verbose_name="二维码地址", max_length=256)
    name = models.CharField(verbose_name="公众号名字", max_length=32)
    logo = models.CharField(verbose_name="logo地址", max_length=256)

    class Meta:
        verbose_name = "公众号信息"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.company
